from rest_framework import serializers
import datetime, requests
from django.db.models import Count, Sum, Max, Min, Avg

from vouchers.models import *
from users.models import Level
from cashbonus.models import *
from merchants.models import *
from equity_mall.utils.sync_img_to_local import make_qrcode5


class LevelModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = Level
        fields = ['id', 'prov_name', 'city_name', 'district_name', 'branch_name']


class AliDiscountCouponListModelSerializer(serializers.ModelSerializer):

    coupon_type_str = serializers.CharField(source='get_coupon_type_display', read_only=True)
    coupon_status_str = serializers.CharField(source='get_coupon_status_display', read_only=True)
    coupon_way_str = serializers.CharField(source='get_coupon_way_display', read_only=True)
    publish_time = serializers.SerializerMethodField(read_only=True)
    coupon_status = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCoupon
        fields = ['id', 'coupon_type', 'coupon_type_str', 'activity_name', 'coupon_status', 'coupon_status_str', 'floor_amount',
                  'publish_time', 'max_number', 'send_count', 'remain_number', 'coupon_way', 'coupon_way_str', 'template_id']

    def get_coupon_status(self, obj):
        try:
            now_date = datetime.datetime.now()
            if obj.coupon_status in [1, 4]:
                if obj.publish_end_time < now_date:
                    obj.coupon_status = 2
                    obj.save()
                    return 2
            # elif obj.coupon_status == 3:
            #     if obj.publish_start_time < now_date:
            #         obj.coupon_status = 1
            #         obj.save()
            #         return 1
            return obj.coupon_status
        except:
            return obj.coupon_status

    def get_publish_time(self, obj):
        try:
            return f'{obj.publish_start_time.strftime("%Y.%m.%d %H:%M:%S")}-{obj.publish_end_time.strftime("%Y.%m.%d %H:%M:%S")}'
        except:
            return ''


class AliDiscountCouponChannelCommonVoucherModelSerializer(serializers.ModelSerializer):

    discount_type_str = serializers.CharField(source='get_discount_type_display', read_only=True)
    bankcard_type_str = serializers.CharField(source='get_bankcard_type_display', read_only=True)
    usetime_type = serializers.SerializerMethodField(read_only=True)
    join_limit_by_user = serializers.SerializerMethodField(read_only=True)
    join_limit_by_bay = serializers.SerializerMethodField(read_only=True)
    distributed_limit_by_time_rules = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCouponChannelCommonVoucher
        fields = ['id', 'discount_type', 'discount_type_str', 'bankcard_type', 'bankcard_type_str', 'usetime_type', 'principal_name',
                  'join_limit_by_user', 'join_limit_by_bay', 'distributed_limit_by_time', 'distributed_limit_by_time_rules']

    def get_distributed_limit_by_time_rules(self, obj):
        data = []
        try:
            alidiscountcoupondistributedlimit_set = obj.alidiscountcoupondistributedlimit_set.all()
            for alidiscountcoupondistributedlimit in alidiscountcoupondistributedlimit_set:
                week_day_dict = {
                    '0': '周一',
                    '1': '周二',
                    '2': '周三',
                    '3': '周四',
                    '4': '周五',
                    '5': '周六',
                    '6': '周日',
                }
                weeks = ''
                for key,value in week_day_dict.items():
                    if key in alidiscountcoupondistributedlimit.weeks:
                        weeks += f'、{value}'
                data.append({
                    "weeks": f'每周 {weeks[1:]}',
                    "enable_time": f'{alidiscountcoupondistributedlimit.start_enable_time.strftime("%H:%M:%S")}-{alidiscountcoupondistributedlimit.end_enable_time.strftime("%H:%M:%S")}'
                })
        except:
            pass
        return data

    def get_usetime_type(self, obj):
        try:
            if obj.usetime_type == 2:
                return f'固定时间段{obj.start_fixed_time.strftime("%Y.%m.%d %H:%M:%S")}-{obj.end_fixed_time.strftime("%Y.%m.%d %H:%M:%S")}'
            elif obj.usetime_type == 3:
                return f'领取后立即生效有效时间{obj.invalid_day}天'
            else:
                return f'领取后次日凌晨生效有效时间{obj.invalid_day}天'
        except:
            return ''

    def get_join_limit_by_user(self, obj):
        try:
            if obj.join_limit_by_user == 1:
                return f'活动期间每个用户可参与{obj.join_limit_by_user_count}次'
            else:
                return '不限制'
        except:
            return ''

    def get_join_limit_by_bay(self, obj):
        try:
            if obj.join_limit_by_bay == 1:
                return f'每个用户每日可参与{obj.join_limit_by_bay_count}次'
            elif obj.join_limit_by_bay == 2:
                return f'每个用户每月可参与{obj.join_limit_by_bay_count}次'
            elif obj.join_limit_by_bay == 4:
                return f'每个用户每周可参与{obj.join_limit_by_bay_count}次'
            else:
                return '不限制'
        except:
            return ''


class AliDiscountCouponRetrieveModelSerializer(serializers.ModelSerializer):

    coupon_type_str = serializers.CharField(source='get_coupon_type_display', read_only=True)
    coupon_status_str = serializers.CharField(source='get_coupon_status_display', read_only=True)
    coupon_way_str = serializers.CharField(source='get_coupon_way_display', read_only=True)
    publish_time = serializers.SerializerMethodField(read_only=True)
    alidiscountcouponchannelcommonvoucher = AliDiscountCouponChannelCommonVoucherModelSerializer()
    level = LevelModelSerializer()
    merchant_list = serializers.SerializerMethodField(read_only=True)
    platform = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    publish_start_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    publish_end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)

    class Meta:
        model = AliDiscountCoupon
        fields = ['id', 'coupon_type', 'coupon_type_str', 'activity_name', 'coupon_status', 'coupon_status_str', 'floor_amount',
                  'publish_time', 'max_number', 'send_count', 'remain_number', 'alidiscountcouponchannelcommonvoucher', 'level',
                  'is_union', 'is_white', 'available_merchants', 'coupon_way', 'coupon_way_str', 'activity_description', 'merchant_list',
                  'create_time', 'template_id', 'platform', 'publish_end_time', 'publish_start_time', 'transaction_minimum', 'amount',
                  'is_need_auth']

    def get_platform(self, obj):
        try:
            platform = obj.platform
            return f'{platform.name}({platform.mchid})'
        except:
            return ''

    def get_merchant_list(self, obj):
        data = []
        try:
            alidiscountcouponmerchant_set = obj.alidiscountcouponmerchant_set.all()
            if alidiscountcouponmerchant_set:
                alidiscountcouponmerchant_set = alidiscountcouponmerchant_set[:6]
                for alidiscountcouponmerchant in alidiscountcouponmerchant_set:
                    merchant = alidiscountcouponmerchant.merchant
                    data.append(f'{merchant.short_name}({merchant.wyfMerchantID})')
        except:
            pass
        return data

    def get_publish_time(self, obj):
        try:
            return f'{obj.publish_start_time.strftime("%Y.%m.%d %H:%M:%S")}-{obj.publish_end_time.strftime("%Y.%m.%d %H:%M:%S")}'
        except:
            return ''


class AliDiscountCouponLevelListModelSerializer(serializers.ModelSerializer):

    level_type = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    wait_number = serializers.SerializerMethodField(read_only=True)
    unclaimed_number = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    p_wait_number = serializers.SerializerMethodField(read_only=True)
    p_unclaimed_number = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCouponLevel
        fields = ['id', 'level_type', 'level_name', 'max_number', 'take_number', 'remain_number', 'wait_number', 'unclaimed_number', 'use_number',
                  'activity_name', 'p_max_number', 'p_take_number', 'p_remain_number', 'p_wait_number', 'p_unclaimed_number', 'p_use_number', 'common_qrcode']

    def get_wait_number(self, obj):
        try:
            wait_number = obj.receive_number - obj.use_number
            return wait_number
        except:
            return ''

    def get_p_wait_number(self, obj):
        try:
            p_wait_number = obj.p_receive_number - obj.p_use_number
            return p_wait_number
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.activity.activity_name
        except:
            return ''

    def get_unclaimed_number(self, obj):
        try:
            unclaimed_number = obj.take_number - obj.receive_number
            return unclaimed_number
        except:
            return ''

    def get_p_unclaimed_number(self, obj):
        try:
            p_unclaimed_number = obj.p_take_number - obj.p_receive_number
            return p_unclaimed_number
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_level_type(self, obj):
        try:
            level = obj.level.level
            if level == 1:
                return '省公司'
            elif level == 2:
                return '市公司'
            elif level == 3:
                return '区县'
            elif level == 4:
                return '网点'
            else:
                return '信翔'
        except:
            return ''


class AliDiscountCouponLevelRetrieveModelSerializer(serializers.ModelSerializer):

    level_type = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    wait_number = serializers.SerializerMethodField(read_only=True)
    unclaimed_number = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCouponLevel
        fields = ['id', 'level_type', 'level_name', 'max_number', 'take_number', 'remain_number', 'wait_number', 'unclaimed_number', 'use_number']

    def get_wait_number(self, obj):
        try:
            wait_number = obj.receive_number - obj.use_number
            return wait_number
        except:
            return ''

    def get_unclaimed_number(self, obj):
        try:
            unclaimed_number = obj.take_number - obj.receive_number
            return unclaimed_number
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_level_type(self, obj):
        try:
            level = obj.level.level
            if level == 1:
                return '省公司'
            elif level == 2:
                return '市公司'
            elif level == 3:
                return '区县'
            elif level == 4:
                return '网点'
            else:
                return '信翔'
        except:
            return ''


class AliDiscountCouponInfoListModelSerializer(serializers.ModelSerializer):

    gmt_create = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    gmt_distributed = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    status_str = serializers.CharField(source='get_status_display', read_only=True)
    customeruser_realname = serializers.SerializerMethodField(read_only=True)
    companyuser_nickname = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    coupon_type = serializers.SerializerMethodField(read_only=True)
    coupon_type_str = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCouponInfo
        fields = ['id', 'gmt_create', 'mobile', 'status', 'status_str', 'gmt_distributed', 'customeruser_realname', 'companyuser_nickname', 'activity_name',
                  'coupon_type', 'coupon_type_str', 'level_name']

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_coupon_type_str(self, obj):
        try:
            return obj.alidiscountcoupon.get_coupon_type_display()
        except:
            return ''

    def get_coupon_type(self, obj):
        try:
            return obj.alidiscountcoupon.coupon_type
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.alidiscountcoupon.activity_name
        except:
            return ''

    def get_customeruser_realname(self, obj):
        try:
            return obj.customer_user.realname
        except:
            return ''

    def get_companyuser_nickname(self, obj):
        try:
            return obj.companyuser.nickname
        except:
            return ''


class AliDiscountCouponInfoRetrieveModelSerializer(serializers.ModelSerializer):

    gmt_use = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    gmt_distributed = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    gmt_undo = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    status_str = serializers.CharField(source='get_status_display', read_only=True)
    customeruser_realname = serializers.SerializerMethodField(read_only=True)
    activity_info = serializers.SerializerMethodField(read_only=True)
    payout_info = serializers.SerializerMethodField(read_only=True)
    mobile = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = AliDiscountCouponInfo
        fields = ['id', 'mobile', 'status', 'status_str', 'customeruser_realname', 'gmt_use', 'gmt_distributed', 'gmt_undo', 'payout_info', 'activity_info', 'order_id',
                  'out_biz_order', 'user_id']

    def get_activity_info(self, obj):
        data = {}
        data['activity_name'] = ''
        data['floor_amount'] = ''
        data['publish_time'] = ''
        data['usetime_type'] = ''
        data['coupon_type'] = ''
        data['coupon_type_str'] = ''
        try:
            activity = obj.alidiscountcoupon
            channelcommonvoucher = activity.alidiscountcouponchannelcommonvoucher
            data['coupon_type_str'] = activity.get_coupon_type_display()
            data['coupon_type'] = activity.coupon_type
            data['floor_amount'] = activity.floor_amount
            data['publish_time'] = f'{activity.publish_start_time.strftime("%Y.%m.%d %H:%M:%S")}-{activity.publish_end_time.strftime("%Y.%m.%d %H:%M:%S")}'
            data['activity_name'] = activity.activity_name
            if channelcommonvoucher.usetime_type == 2:
                data['usetime_type'] = f'固定时间段{channelcommonvoucher.start_fixed_time.strftime("%Y.%m.%d %H:%M:%S")}-{channelcommonvoucher.end_fixed_time.strftime("%Y.%m.%d %H:%M:%S")}'
            elif channelcommonvoucher.usetime_type == 3:
                data['usetime_type'] = f'领取后立即生效有效时间{channelcommonvoucher.invalid_day}天'
            else:
                data['usetime_type'] = f'领取后次日凌晨生效有效时间{channelcommonvoucher.invalid_day}天'
            if channelcommonvoucher.join_limit_by_user == 1:
                data['join_limit_by_user'] = f'活动期间每个用户可参与{channelcommonvoucher.join_limit_by_user_count}次'
            else:
                data['join_limit_by_user'] = '不限制'
            if channelcommonvoucher.join_limit_by_bay == 1:
                data['join_limit_by_bay'] = f'每个用户每日可参与{channelcommonvoucher.join_limit_by_bay_count}次'
            if channelcommonvoucher.join_limit_by_bay == 2:
                data['join_limit_by_bay'] = f'每个用户每月可参与{channelcommonvoucher.join_limit_by_bay_count}次'
            elif channelcommonvoucher.join_limit_by_bay == 4:
                data['join_limit_by_bay'] = f'每个用户每周可参与{channelcommonvoucher.join_limit_by_bay_count}次'
            else:
                data['join_limit_by_bay'] = '不限制'
        except:
            pass
        return data

    def get_payout_info(self, obj):
        data = {}
        data['alidiscountcoupon_id'] = ''
        data['level_name'] = ''
        data['companyuser_nickname'] = ''
        data['gmt_create'] = ''
        try:
            data['alidiscountcoupon_id'] = obj.alidiscountcoupon_id
            data['companyuser_nickname'] = obj.companyuser.nickname
            data['gmt_create'] = obj.gmt_create.strftime("%Y-%m-%d %H:%M:%S")
            data['level_name'] = obj.level.name
        except:
            pass
        return data

    def get_customeruser_realname(self, obj):
        try:
            if obj.customer_user:
                realname = obj.customer_user.realname
            else:
                realname = obj.customeruservice.realname
            return f'{realname.replace(realname[-2], "*", 1)}'
        except:
            return ''

    def get_mobile(self, obj):
        try:
            mobile = obj.mobile
            return f'{mobile[:3]}****{mobile[-4:]}'
        except:
            return ''


class CashActivityListModelSerializer(serializers.ModelSerializer):

    activity_type_str = serializers.CharField(source='get_activity_type_display', read_only=True)
    activity_state_str = serializers.CharField(source='get_activity_state_display', read_only=True)
    rule = serializers.SerializerMethodField(read_only=True)
    activity_state = serializers.SerializerMethodField(read_only=True)
    available_begin_time = serializers.DateTimeField(format="%Y.%m.%d %H:%M:%S", required=False)
    available_end_time = serializers.DateTimeField(format="%Y.%m.%d %H:%M:%S", required=False)
    publish_time = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivity
        fields = ['id', 'name', 'activity_type', 'activity_type_str', 'activity_state', 'activity_state_str', 'max_amount', 'remain_amount', 'available_begin_time', 'available_end_time', 'rule', 'publish_time',
                  'level_name']

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_publish_time(self, obj):
        try:
            return f'{obj.available_begin_time.strftime("%Y.%m.%d %H:%M:%S")}-{obj.available_end_time.strftime("%Y.%m.%d %H:%M:%S")}'
        except:
            return ''

    def get_activity_state(self, obj):
        try:
            now_date = datetime.datetime.now()
            if obj.activity_state != 4 and obj.available_end_time < now_date:
                obj.activity_state = 4
                obj.save()
                return 4
            return obj.activity_state
        except:
            return obj.activity_state

    def get_rule(self, obj):
        try:
            if obj.activity_type in [1, 4, 8]:
                return f'{obj.min_distributed_amount}-{obj.max_distributed_amount}'
            else:
                cashactivityrule_set = obj.cashactivityrule_set.filter(is_delete=0).order_by('amount')
                result = ''
                for cashactivityrule in cashactivityrule_set:
                    result += f'{cashactivityrule.amount},'
                return result[:-1]
        except:
            return ''


class CashActivityRuleModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = CashActivityRule
        fields = ['id', 'amount', 'probability']


class CashActivityRetrieveModelSerializer(serializers.ModelSerializer):

    activity_type_str = serializers.CharField(source='get_activity_type_display', read_only=True)
    activity_state_str = serializers.CharField(source='get_activity_state_display', read_only=True)
    is_check_identity_str = serializers.CharField(source='get_is_check_identity_display', read_only=True)
    rule = serializers.SerializerMethodField(read_only=True)
    available_begin_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    available_end_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    level = serializers.SerializerMethodField(read_only=True)
    can_remain_amount = serializers.SerializerMethodField(read_only=True)
    cashactivityrule_set = CashActivityRuleModelSerializer(many=True)
    developer_set = serializers.SerializerMethodField(read_only=True)
    id = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivity
        fields = ['id', 'name', 'activity_type', 'activity_type_str', 'activity_state', 'activity_state_str', 'max_amount', 'remain_amount', 'available_begin_time', 'available_end_time', 'rule',
                  'activity_description', 'create_time', 'level', 'can_remain_amount', 'is_max_amount_by_day', 'is_max_amount_by_user_by_day', 'is_max_amount_by_user',
                  'is_max_amount_by_customeruser', 'max_amount_by_day', 'max_amount_by_user_by_day', 'max_amount_by_user', 'max_amount_by_customeruser', 'cashactivityrule_set',
                  'is_need_auth', 'is_check_identity', 'is_check_identity_str', 'developer_set',
                  'is_push_ylx']

    def get_id(self, obj):
        try:
            return obj.activity_id
        except:
            return ''

    def get_developer_set(self, obj):
        data = []
        try:
            developer_set = CashActivityAPIRelation.objects.filter(cashactivity_id=obj.id)
            for developer in developer_set:
                user = developer.developer
                data.append({
                    'id': developer.id,
                    'account': user.account,
                    'nickname': user.nickname
                })
        except:
            pass
        return data

    def get_can_remain_amount(self, obj):
        try:
            max_amount__sum = obj.cashactivitylevel_set.all().aggregate(Sum('max_amount'))['max_amount__sum']
            if max_amount__sum:
                remain_amount = obj.max_amount - max_amount__sum
            else:
                remain_amount = obj.max_amount
            return remain_amount
        except:
            return 0

    def get_rule(self, obj):
        try:
            if obj.activity_type in [1, 4, 8]:
                return f'{obj.min_distributed_amount}-{obj.max_distributed_amount}'
            else:
                cashactivityrule_set = obj.cashactivityrule_set.filter(is_delete=0).order_by('amount')
                result = ''
                for cashactivityrule in cashactivityrule_set:
                    result += f'{cashactivityrule.amount},'
                return result[:-1]
        except:
            return ''

    def get_level(self, obj):
        data = {
            'prov_name': '',
            'city_name': '',
            'district_name': '',
            'branch_name': '',
            'account': ''
        }
        try:
            level = obj.level
            data['prov_name'] = level.prov_name
            data['city_name'] = level.city_name
            data['district_name'] = level.district_name
            data['branch_name'] = level.branch_name
            data['account'] = level.account
            return data
        except:
            return data


class CashActivityLevelStatisticalModelSerializer(serializers.ModelSerializer):

    child_list = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    level_type = serializers.SerializerMethodField(read_only=True)
    amountData = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivityLevel
        fields = ['level_name', 'level_type', 'p_max_amount', 'p_take_amount', 'p_remain_amount', 'amountData', 'child_list']

    def get_level_name(self, obj):
        return obj.level.name

    def get_level_type(self, obj):
        level = obj.level.level
        if level == 1:
            return '省公司'
        elif level == 2:
            return '市公司'
        elif level == 3:
            return '区县'
        elif level == 4:
            return '网点'
        else:
            return '信翔'

    def get_amountData(self, obj):
        data = [
            {"name": "已派发", "value": obj.p_take_amount},
            {"name": "剩余额度", "value": obj.p_remain_amount},
            {"name": "总额度", "value": obj.p_max_amount}
        ]
        return data

    def get_child_list(self, obj):
        level = obj.level
        if level.level == 1:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=2)
            return CashActivityLevelStatisticalModelSerializer(list_queryset, many=True).data
        elif level.level == 2:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=3)
            return CashActivityLevelStatisticalModelSerializer(list_queryset, many=True).data
        elif level.level == 3:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=4)
            return CashActivityLevelStatisticalModelSerializer(list_queryset, many=True).data
        elif level.level == 4:
            return []
        else:
            return []


class CashActivityLevelTreeModelSerializer(serializers.ModelSerializer):

    level_type = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    p_unclaimed_amount = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    is_auth_str = serializers.CharField(source='get_is_auth_display', read_only=True)
    child_list = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivityLevel
        fields = ['id', 'level_type', 'level_name', 'remain_amount', 'activity_name',
                  'p_receive_amount', 'p_remain_amount', 'p_take_amount', 'p_max_amount', 'p_unclaimed_amount', 'is_auth', 'is_auth_str',
                  'child_list']

    def get_p_unclaimed_amount(self, obj):
        try:
            p_unclaimed_amount = obj.p_take_amount - obj.p_receive_amount
            return p_unclaimed_amount
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.cash_activity.name
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_level_type(self, obj):
        try:
            level = obj.level.level
            if level == 1:
                return '省公司'
            elif level == 2:
                return '市公司'
            elif level == 3:
                return '区县'
            elif level == 4:
                return  '网点'
            else:
                return '信翔'
        except:
            return ''

    def get_child_list(self, obj):
        level = obj.level
        if level.level == 1:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=2)
            return CashActivityLevelTreeModelSerializer(list_queryset, many=True).data
        elif level.level == 2:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=3)
            return CashActivityLevelTreeModelSerializer(list_queryset, many=True).data
        elif level.level == 3:
            list_queryset = CashActivityLevel.objects.filter(child_set__parent_id=obj.id, level__level=4)
            return CashActivityLevelTreeModelSerializer(list_queryset, many=True).data
        elif level.level == 4:
            return []
        else:
            return []


class CashActivityLevelListModelSerializer(serializers.ModelSerializer):

    level_type = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    p_unclaimed_amount = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    is_auth_str = serializers.CharField(source='get_is_auth_display', read_only=True)

    class Meta:
        model = CashActivityLevel
        fields = ['id', 'level_type', 'level_name', 'remain_amount', 'activity_name',
                  'p_receive_amount', 'p_remain_amount', 'p_take_amount', 'p_max_amount', 'p_unclaimed_amount', 'is_auth', 'is_auth_str']

    def get_p_unclaimed_amount(self, obj):
        try:
            p_unclaimed_amount = obj.p_take_amount - obj.p_receive_amount
            return p_unclaimed_amount
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.cash_activity.name
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_level_type(self, obj):
        try:
            level = obj.level.level
            if level == 1:
                return '省公司'
            elif level == 2:
                return '市公司'
            elif level == 3:
                return '区县'
            elif level == 4:
                return '网点'
            else:
                return '信翔'
        except:
            return ''


class CashActivityLevelRetrieveModelSerializer(serializers.ModelSerializer):

    level_type = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    unclaimed_amount = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    can_amount = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivityLevel
        fields = ['id', 'level_type', 'level_name', 'max_amount', 'take_amount', 'remain_amount', 'unclaimed_amount', 'receive_amount', 'activity_name', 'can_amount']

    def get_can_amount(self, obj):
        data = {}
        data['max_amount'] = 0
        data['min_amount'] = 0
        try:
            cash_activity = obj.cash_activity
            max_amount__sum = cash_activity.cashactivitylevel_set.all().aggregate(Sum('max_amount'))['max_amount__sum']
            if max_amount__sum:
                remain_amount = cash_activity.max_amount - max_amount__sum
            else:
                remain_amount = cash_activity.max_amount
            data['max_amount'] = obj.max_amount + remain_amount
            data['min_amount'] = obj.max_amount - obj.remain_amount
        except:
            pass
        return data

    def get_unclaimed_amount(self, obj):
        try:
            unclaimed_amount = obj.take_amount - obj.receive_amount
            return unclaimed_amount
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.cash_activity.name
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_level_type(self, obj):
        try:
            level = obj.level.level
            if level == 1:
                return '省公司'
            elif level == 2:
                return '市公司'
            elif level == 3:
                return '区县'
            elif level == 4:
                return '网点'
            else:
                return '信翔'
        except:
            return ''


class CashActivityDataListModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    received_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    state_str = serializers.CharField(source='get_state_display', read_only=True)
    customeruser_realname = serializers.SerializerMethodField(read_only=True)
    companyuser_nickname = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    activity_type = serializers.SerializerMethodField(read_only=True)
    activity_type_str = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    city_name = serializers.SerializerMethodField(read_only=True)
    district_name = serializers.SerializerMethodField(read_only=True)
    mobile = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivityData
        fields = ['id', 'create_time', 'mobile', 'state', 'state_str', 'received_time', 'customeruser_realname', 'companyuser_nickname', 'activity_name',
                  'activity_type', 'activity_type_str', 'level_name', 'amount', 'city_name', 'district_name']

    def get_city_name(self, obj):
        try:
            return obj.level.city_name
        except:
            return ''

    def get_district_name(self, obj):
        try:
            return obj.level.district_name
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_activity_type_str(self, obj):
        try:
            return obj.cash_activity.get_activity_type_display()
        except:
            return ''

    def get_activity_type(self, obj):
        try:
            return obj.cash_activity.activity_type
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.cash_activity.name
        except:
            return ''

    def get_customeruser_realname(self, obj):
        try:
            return obj.customer_user.realname
        except:
            return ''

    def get_mobile(self, obj):
        try:
            if obj.customer_user:
                mobile = obj.customer_user.mobile
            elif obj.customeruservice:
                mobile = obj.customeruservice.mobile
            else:
                mobile = obj.mobile
            return f'{mobile[:3]}****{mobile[-4:]}'
        except:
            return ''

    def get_companyuser_nickname(self, obj):
        try:
            nickname = obj.companyuser.nickname
            return f'{nickname.replace(nickname[-2], "*", 1)}'
        except:
            return ''


class CashActivityDataRetrieveModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    received_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    expired_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    state_str = serializers.CharField(source='get_state_display', read_only=True)
    customeruser_realname = serializers.SerializerMethodField(read_only=True)
    companyuser_nickname = serializers.SerializerMethodField(read_only=True)
    activity_name = serializers.SerializerMethodField(read_only=True)
    activity_type = serializers.SerializerMethodField(read_only=True)
    activity_type_str = serializers.SerializerMethodField(read_only=True)
    level_name = serializers.SerializerMethodField(read_only=True)
    mobile = serializers.SerializerMethodField(read_only=True)
    mchid = serializers.SerializerMethodField(read_only=True)
    city_name = serializers.SerializerMethodField(read_only=True)
    district_name = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = CashActivityData
        fields = ['id', 'create_time', 'mobile', 'state', 'state_str', 'received_time', 'customeruser_realname', 'companyuser_nickname', 'activity_name',
                  'activity_type', 'activity_type_str', 'level_name', 'amount', 'expired_time', 'payment_no', 'cash_activity_id', 'return_msg', 'mchid', 'payeeFullName',
                  'city_name', 'district_name']

    def get_city_name(self, obj):
        try:
            return obj.level.city_name
        except:
            return ''

    def get_district_name(self, obj):
        try:
            return obj.level.district_name
        except:
            return ''

    def get_level_name(self, obj):
        try:
            return obj.level.name
        except:
            return ''

    def get_mchid(self, obj):
        try:
            channel = obj.channel
            if channel:
                return f'{channel.name}({channel.mchid})'
            else:
                return ''
            # if obj.mchid == '1486198522':
            #     return '信翔商户(1486198522)'
            # elif obj.mchid == '1571060401':
            #     return '信亨商户(1571060401)'
            # elif obj.mchid == 'wx':
            #     return '信翔商户(1486198522)'
            # elif obj.mchid == 'alipay':
            #     return '信翔支付宝服务商(2088631976752358)'
            # else:
            #     return ''
        except:
            return ''

    def get_activity_type_str(self, obj):
        try:
            return obj.cash_activity.get_activity_type_display()
        except:
            return ''

    def get_activity_type(self, obj):
        try:
            return obj.cash_activity.activity_type
        except:
            return ''

    def get_activity_name(self, obj):
        try:
            return obj.cash_activity.name
        except:
            return ''

    def get_customeruser_realname(self, obj):
        try:
            realname = obj.customer_user.realname
            return f'{realname.replace(realname[-2], "*", 1)}'
        except:
            return ''

    def get_mobile(self, obj):
        try:
            if obj.customer_user:
                mobile = obj.customer_user.mobile
            elif obj.customeruservice:
                mobile = obj.customeruservice.mobile
            else:
                mobile = obj.mobile
            return f'{mobile[:3]}****{mobile[-4:]}'
        except:
            return ''

    def get_companyuser_nickname(self, obj):
        try:
            nickname = obj.companyuser.nickname
            return f'{nickname.replace(nickname[-2], "*", 1)}'
        except:
            return ''


class MerchantBankQRCodeQuestModelSerializer(serializers.ModelSerializer):

    create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    file_type_str = serializers.CharField(source='get_file_type_display', read_only=True)
    file_status_str = serializers.CharField(source='get_file_status_display', read_only=True)
    create_user = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantBankQRCodeQuest
        fields = ['id', 'create_time', 'file', 'logs_file', 'file_type', 'file_type_str', 'file_status', 'file_status_str',
                  'total_line', 'success_line', 'error_line', 'remark', 'create_user']

    def get_create_user(self, obj):
        try:
            nickname = obj.create_user.nickname
            return f'{nickname.replace(nickname[-2], "*", 1)}'
        except:
            return ''


class MerchantBankQRCodeListModelSerializer(serializers.ModelSerializer):

    merchant = serializers.SerializerMethodField(read_only=True)
    is_download_str = serializers.CharField(source='get_is_download_display', read_only=True)

    class Meta:
        model = MerchantBankQRCode
        fields = ['id', 'merchant', 'code_id', 'link', 'is_download', 'is_download_str', 'visit', 'total_number', 'total_first_number']

    def get_merchant(self, obj):
        data = {}
        data['id'] = ''
        data['merchant_name'] = ''
        data['business_no'] = ''
        data['prov_name'] = ''
        data['city_name'] = ''
        data['district_name'] = ''
        data['branch_name'] = ''
        data['account_nine'] = ''
        try:
            merchant = obj.merchant
            level = obj.level
            data['id'] = merchant.id
            data['merchant_name'] = merchant.name
            data['business_no'] = merchant.wyfMerchantID
            data['prov_name'] = level.prov_name
            data['city_name'] = level.city_name
            data['district_name'] = level.district_name
            data['branch_name'] = level.branch_name
            data['account_nine'] = level.account_nine
        except:
            pass
        return data


class MerchantBankQRCodeRetrieveModelSerializer(serializers.ModelSerializer):

    merchant = serializers.SerializerMethodField(read_only=True)
    qrcode = serializers.SerializerMethodField(read_only=True)
    bind_number = serializers.SerializerMethodField(read_only=True)
    create_time = serializers.SerializerMethodField(read_only=True)
    is_download_str = serializers.CharField(source='get_is_download_display', read_only=True)

    class Meta:
        model = MerchantBankQRCode
        fields = ['id', 'merchant', 'code_id', 'qrcode', 'link', 'bind_number', 'parent_code_id', 'create_time', 'is_download', 'is_download_str', 'visit',
                  'total_number', 'total_first_number']

    def get_create_time(self, obj):
        try:
            return obj.quest.create_time.strftime("%Y-%m-%d %H:%M:%S")
        except:
            return ''

    def get_merchant(self, obj):
        data = {}
        data['id'] = ''
        data['merchant_name'] = ''
        data['business_no'] = ''
        data['prov_name'] = ''
        data['city_name'] = ''
        data['district_name'] = ''
        data['branch_name'] = ''
        data['account_nine'] = ''
        try:
            merchant = obj.merchant
            level = obj.level
            data['id'] = merchant.id
            data['merchant_name'] = merchant.name
            data['business_no'] = merchant.wyfMerchantID
            data['prov_name'] = level.prov_name
            data['city_name'] = level.city_name
            data['district_name'] = level.district_name
            data['branch_name'] = level.branch_name
            data['account_nine'] = level.account_nine
        except:
            pass
        return data

    def get_qrcode(self, obj):
        try:
            if not obj.qrcode:
                link = obj.link
                url = 'https://partner.douyinpay.com/api/merchant/getBankSubQrCodeValue'
                body = {
                    "code_id": obj.code_id,
                    "sign": link.replace(f'https://partner.douyinpay.com/external/bankcode?code_id={obj.code_id}&sign=', '')
                }
                response = requests.post(url=url, json=body)
                result = response.json()
                code_url = result['code_url']
                parent_code_id = result['parent_code_id']
                qrcode = make_qrcode5(obj.code_id, code_url, None)
                obj.qrcode = qrcode
                obj.parent_code_id = parent_code_id
                obj.save()
                return f'https://circle.sutpay.cn/{qrcode}'
            else:
                return obj.qrcode.url
        except:
            return ''

    def get_bind_number(self, obj):
        data = {}
        data['total_number'] = 0
        data['total_first_number'] = 0
        data['last_month_number'] = 0
        data['last_month_first_number'] = 0
        data['this_month_number'] = 0
        data['this_month_first_number'] = 0
        data['yesterday_number'] = 0
        data['yesterday_first_number'] = 0
        try:
            today = datetime.datetime.now()
            yesterday = today + datetime.timedelta(-1)
            yesterday_begin = yesterday.strftime("%Y-%m-%d 00:00:00")
            yesterday_end = yesterday.strftime("%Y-%m-%d 23:59:59")
            last_month_begin = (today.replace(day=1) + datetime.timedelta(-1)).replace(day=1).strftime("%Y-%m-%d 00:00:00")
            last_month_end = (today.replace(day=1) + datetime.timedelta(-1)).strftime("%Y-%m-%d 23:59:59")
            this_month_begin = today.replace(day=1).strftime("%Y-%m-%d 00:00:00")
            this_month_end = today.strftime("%Y-%m-%d 23:59:59")
            total_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id).count()
            total_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1).count()
            last_month_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=last_month_begin, bind_time__lte=last_month_end).count()
            last_month_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=last_month_begin, bind_time__lte=last_month_end).count()
            this_month_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=this_month_begin, bind_time__lte=this_month_end).count()
            this_month_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=this_month_begin, bind_time__lte=this_month_end).count()
            yesterday_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, bind_time__gte=yesterday_begin, bind_time__lte=yesterday_end).count()
            yesterday_first_number = MerchantBankQRCodeBindData.objects.filter(merchant_id=obj.merchant_id, is_first=1, bind_time__gte=yesterday_begin, bind_time__lte=yesterday_end).count()
            data['total_number'] = total_number
            data['total_first_number'] = total_first_number
            data['last_month_number'] = last_month_number
            data['last_month_first_number'] = last_month_first_number
            data['this_month_number'] = this_month_number
            data['this_month_first_number'] = this_month_first_number
            data['yesterday_number'] = yesterday_number
            data['yesterday_first_number'] = yesterday_first_number
        except:
            pass
        return data


class MerchantBankQRCodeBindDataListModelSerializer(serializers.ModelSerializer):

    is_first_str = serializers.CharField(source='get_is_first_display', read_only=True)
    card_type_str = serializers.CharField(source='get_card_type_display', read_only=True)
    bind_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
    merchant = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MerchantBankQRCodeBindData
        fields = ['id', 'code_id', 'card_number', 'is_first', 'is_first_str', 'card_type', 'card_type_str', 'bind_time', 'merchant']

    def get_merchant(self, obj):
        data = {}
        data['id'] = ''
        data['merchant_name'] = ''
        data['business_no'] = ''
        data['city_name'] = ''
        data['district_name'] = ''
        data['branch_name'] = ''
        data['account_nine'] = ''
        try:
            merchant = obj.merchant
            level = obj.level
            data['id'] = merchant.id
            data['merchant_name'] = merchant.name
            data['business_no'] = merchant.wyfMerchantID
            data['city_name'] = level.city_name
            data['district_name'] = level.district_name
            data['branch_name'] = level.branch_name
            data['account_nine'] = level.account_nine
        except:
            pass
        return data


class MErchantBankQPCodeStatisticsListModelSerializer(serializers.ModelSerializer):

    bind_time = serializers.DateTimeField(format="%Y-%m-%d", required=False)
    merchant = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = MErchantBankQPCodeStatistics
        fields = ['id', 'code_id', 'bind_time', 'merchant', 'total_number', 'total_first_number']

    def get_merchant(self, obj):
        data = {}
        data['merchant_name'] = ''
        data['business_no'] = ''
        data['city_name'] = ''
        data['district_name'] = ''
        data['branch_name'] = ''
        data['account_nine'] = ''
        try:
            merchant = obj.merchant
            level = obj.level
            data['merchant_name'] = merchant.name
            data['business_no'] = merchant.wyfMerchantID
            data['city_name'] = level.city_name
            data['district_name'] = level.district_name
            data['branch_name'] = level.branch_name
            data['account_nine'] = level.account_nine
        except:
            pass
        return data